#include "slog2_context.h"
#include "common.h"
#include <iostream>

Slog2ReturnValue Slog2Context::Initialize(
		const std::string contextid,
	       	const std::string description,
		Slog2VerbosityLevel verbosity)
{
    contextid_ = contextid;
    description_ = description;
    verbosity_ = verbosity;

    return Slog2ReturnValue::kReturnOk;
}

Slog2ReturnValue Slog2Context::Register()
{

    config_.buffer_set_name = contextid_.c_str();
    config_.num_buffers = 1;
    config_.verbosity_level = toVerbosity(verbosity_);
    config_.buffer_config[0].buffer_name = "default_context";
    config_.buffer_config[0].num_pages = 40;

    int ret = slog2_register(&config_, &handle_, SLOG2_ALLOC_TYPE_SHMEM | SLOG2_DISCARD_NEWLINE);
    if (0 != ret) {
        std::cerr << "slog2_register fail, ret:" << ret << ", errno:" << errno << std::endl;
        return Slog2ReturnValue::kReturnError;
    }

    // set default buffer for logging
    (void)slog2_set_default_buffer(handle_);

    return Slog2ReturnValue::kReturnOk;
}

Slog2ReturnValue Slog2Context::Unregister()
{
    int ret = slog2_reset();
    if (0 != ret) {
        std::cerr << "slog2_reset fail, ret:" << ret << ", errno:" << errno << std::endl;
        return Slog2ReturnValue::kReturnError;
    }

    return Slog2ReturnValue::kReturnOk;
}

bool Slog2Context::IsConsoleEnabled()
{
    return console_enabled_;
}

Slog2ReturnValue Slog2Context::EnableConsole(bool enable)
{
    console_enabled_ = enable;
    return Slog2ReturnValue::kReturnOk;
}

bool Slog2Context::IsRemoteEnabled()
{
    return remote_enabled_;
}

Slog2ReturnValue Slog2Context::EnableRemote(bool enable)
{
    remote_enabled_ = enable;
    return Slog2ReturnValue::kReturnOk;
}

slog2_buffer_t Slog2Context::GetDefaultBuffer()
{
  return slog2_set_default_buffer((slog2_buffer_t)-1);
}

uint8_t Slog2Context::toVerbosity(Slog2VerbosityLevel verbosity_level)
{
    uint8_t verbosity = SLOG2_SHUTDOWN;
    switch (verbosity_level)
    {
        case Slog2VerbosityLevel::kShutdown:
            verbosity = SLOG2_SHUTDOWN;
            break;
        case Slog2VerbosityLevel::kCritical:
            verbosity = SLOG2_CRITICAL;
            break;
        case Slog2VerbosityLevel::kError:
            verbosity = SLOG2_ERROR;
            break;
        case Slog2VerbosityLevel::kWarning:
            verbosity = SLOG2_WARNING;
            break;
        case Slog2VerbosityLevel::kNotice:
            verbosity = SLOG2_NOTICE;
            break;
        case Slog2VerbosityLevel::kInfo:
            verbosity = SLOG2_INFO;
            break;
        case Slog2VerbosityLevel::kDebug1:
            verbosity = SLOG2_DEBUG1;
            break;
        case Slog2VerbosityLevel::kDebug2:
            verbosity = SLOG2_DEBUG2;
            break;
        default:
            std::cerr << "unknown verbosity_level:"
		      << to_integral(verbosity_level)
		      << std::endl;
            break;
    }

    return verbosity;
}

